﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClientOperationContractGenerater
{
    class StaticData
    {        
        public const string Script =
        @"
        
        ////////////////////////////////////////////
        ////////////Interface Script////////////////
        ////////////////////////////////////////////

        //----------------
        [OperationContractAttribute(AsyncPattern = true,
                                    Action = ""@Namespace/@ServiceName/@OperationContractName"",
                                    ReplyAction = ""@Namespace/@ServiceName/@OperationContractNameResponse"")]
        IAsyncResult Begin@OperationContractName(@ParamsWithComma AsyncCallback callback, object asyncState);

        @Feedback End@OperationContractName(IAsyncResult result);
        
        ////////////////////////////////////////////
        ///////////Implementation Script////////////
        ////////////////////////////////////////////

        #region @OperationContractName

        public event EventHandler<@EventArgs> @OperationContractNameCompleted;

        [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
        IAsyncResult I@ServiceName.Begin@OperationContractName(@ParamsWithComma AsyncCallback callback, object asyncState)
        {
            return Channel.Begin@OperationContractName(@ParamNamesWithComma callback, asyncState);
        }

        [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
        @Feedback I@ServiceName.End@OperationContractName(IAsyncResult result)
        {
            return Channel.End@OperationContractName(result);
        }

        private IAsyncResult OnBegin@OperationContractName(object[] inValues, AsyncCallback callback, object asyncState)
        {
            @ParamInits
            return ((I@ServiceName)(this)).Begin@OperationContractName(@ParamNamesWithComma callback, asyncState);
        }

        private object[] OnEnd@OperationContractName(IAsyncResult result)
        {
            @Feedback retVal = ((I@ServiceName)(this)).End@OperationContractName(result);
            return new object[] {
                retVal};
        }

        private void On@OperationContractNameCompleted(object state)
        {
            if ((@OperationContractNameCompleted != null))
            {
                InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state));
                @OperationContractNameCompleted(this, new @EventArgs(e.Results, e.Error, e.Cancelled, e.UserState));
            }
        }

        public void @OperationContractNameAsync(@Params)
        {
            @OperationContractNameAsync(@ParamNamesWithComma null);
        }

        public void @OperationContractNameAsync(@ParamsWithComma object userState)
        {
            if ((onBegin@OperationContractNameDelegate == null))
            {
                onBegin@OperationContractNameDelegate = new BeginOperationDelegate(OnBegin@OperationContractName);
            }
            if ((onEnd@OperationContractNameDelegate == null))
            {
                onEnd@OperationContractNameDelegate = new EndOperationDelegate(OnEnd@OperationContractName);
            }
            if ((on@OperationContractNameCompletedDelegate == null))
            {
                on@OperationContractNameCompletedDelegate = new SendOrPostCallback(On@OperationContractNameCompleted);
            }
            InvokeAsync(onBegin@OperationContractNameDelegate, new object[] {
                    @ParamNames}, onEnd@OperationContractNameDelegate, on@OperationContractNameCompletedDelegate, userState);
        }

        private BeginOperationDelegate onBegin@OperationContractNameDelegate;

        private EndOperationDelegate onEnd@OperationContractNameDelegate;

        private SendOrPostCallback on@OperationContractNameCompletedDelegate;

        private partial class @ServiceNameClientChannel
        {
            public IAsyncResult Begin@OperationContractName(@ParamsWithComma AsyncCallback callback, object asyncState)
            {
                @Args
                IAsyncResult _result = BeginInvoke(""@OperationContractName"", _args, callback, asyncState);
                return _result;
            }

            public @Feedback End@OperationContractName(IAsyncResult result)
            {
                object[] _args = new object[0];
                @Feedback _result = ((@Feedback)(EndInvoke(""@OperationContractName"", _args, result)));
                return _result;
            }
        }

        #endregion
        ";

        public const string InterfaceScript =
        @"
        //----------------
        [OperationContractAttribute(AsyncPattern = true,
                                    Action = ""@Namespace/@ServiceName/@OperationContractName"",
                                    ReplyAction = ""@Namespace/@ServiceName/@OperationContractNameResponse"")]
        IAsyncResult Begin@OperationContractName(@ParamsWithComma AsyncCallback callback, object asyncState);

        @Feedback End@OperationContractName(IAsyncResult result);
        ";

        public const string ClassScript =
        @"
        #region @OperationContractName

        public event EventHandler<@EventArgs> @OperationContractNameCompleted;

        [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
        IAsyncResult I@ServiceName.Begin@OperationContractName(@ParamsWithComma AsyncCallback callback, object asyncState)
        {
            return Channel.Begin@OperationContractName(@ParamNamesWithComma callback, asyncState);
        }

        [EditorBrowsableAttribute(EditorBrowsableState.Advanced)]
        @Feedback I@ServiceName.End@OperationContractName(IAsyncResult result)
        {
            return Channel.End@OperationContractName(result);
        }

        private IAsyncResult OnBegin@OperationContractName(object[] inValues, AsyncCallback callback, object asyncState)
        {
            @ParamInits
            return ((I@ServiceName)(this)).Begin@OperationContractName(@ParamNamesWithComma callback, asyncState);
        }

        private object[] OnEnd@OperationContractName(IAsyncResult result)
        {
            @Feedback retVal = ((I@ServiceName)(this)).End@OperationContractName(result);
            return new object[] {retVal};
        }

        private void On@OperationContractNameCompleted(object state)
        {
            if ((@OperationContractNameCompleted != null))
            {
                InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state));
                @OperationContractNameCompleted(this, new @EventArgs(e.Results, e.Error, e.Cancelled, e.UserState));
            }
        }

        public void @OperationContractNameAsync(@Params)
        {
            @OperationContractNameAsync(@ParamNamesWithComma null);
        }

        public void @OperationContractNameAsync(@ParamsWithComma object userState)
        {
            if ((onBegin@OperationContractNameDelegate == null))
            {
                onBegin@OperationContractNameDelegate = new BeginOperationDelegate(OnBegin@OperationContractName);
            }
            if ((onEnd@OperationContractNameDelegate == null))
            {
                onEnd@OperationContractNameDelegate = new EndOperationDelegate(OnEnd@OperationContractName);
            }
            if ((on@OperationContractNameCompletedDelegate == null))
            {
                on@OperationContractNameCompletedDelegate = new SendOrPostCallback(On@OperationContractNameCompleted);
            }
            InvokeAsync(onBegin@OperationContractNameDelegate, new object[] {
                    @ParamNames}, onEnd@OperationContractNameDelegate, on@OperationContractNameCompletedDelegate, userState);
        }

        private BeginOperationDelegate onBegin@OperationContractNameDelegate;

        private EndOperationDelegate onEnd@OperationContractNameDelegate;

        private SendOrPostCallback on@OperationContractNameCompletedDelegate;

        private partial class @ServiceNameClientChannel
        {
            public IAsyncResult Begin@OperationContractName(@ParamsWithComma AsyncCallback callback, object asyncState)
            {
                @Args
                IAsyncResult _result = BeginInvoke(""@OperationContractName"", _args, callback, asyncState);
                return _result;
            }

            public @Feedback End@OperationContractName(IAsyncResult result)
            {
                object[] _args = new object[0];
                @Feedback _result = ((@Feedback)(EndInvoke(""@OperationContractName"", _args, result)));
                return _result;
            }
        }

        #endregion
        ";

        public const string ArgsBase = @"object[] _args = new object[@NumberOfParams];
                ";
        public const string ArgsAssign = @"_args[@ParamIndex] = @ParamName;
                ";
        public const string ParamInit = @"@DataType @ParamName = (@DataType) inValues[@ParamIndex]; 
            ";

        public const string ServiceName = @"@ServiceName";
        public const string Namespace = @"@Namespace";

        public const string ParamIndex = @"@ParamIndex";
        public const string ParamName = @"@ParamName";
        public const string DataType = @"@DataType";
        
        public const string OperationContractName = @"@OperationContractName";
        public const string ParamInits = @"@ParamInits";
        public const string NumberOfParams = @"@NumberOfParams";
        public const string EventArgs = @"@EventArgs";
        public const string Feedback = @"@Feedback";
        public const string Args = @"@Args";

        public const string Params = @"@Params";
        public const string ParamsWithComma = @"@ParamsWithComma";
        public const string ParamNames = @"@ParamNames";
        public const string ParamNamesWithComma = @"@ParamNamesWithComma";

        public const string RegionMark = "#region";
        public const string EndregionMark = "#endregion";
        public const string EndlineMark = "/n";
        public const string NamespaceMark = "namespace";
        public const string OperationContractMark = "[OperationContract]";

        public const string ClassDeclaration =
        @"
        public partial class @ServiceNameClient 
        {
        ";

        public const string CloseBrace = 
        @"
        }";
        public const string ClassRegionFileNameTemplate = @"D:\Temp\@ServiceNameClient_@Region.cs";
        public const string ClassFileNameTemplate = @"D:\Temp\@ServiceNameClient.cs";
        public const string Region = "@Region";
        public const string InterfaceFileNameTemplate = @"D:\Temp\I@ServiceName.cs";
    }
}
